package com.xzc.one.common.aop;

import com.alibaba.fastjson.JSON;
import com.xzc.one.common.inout.Request;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

@Slf4j
@Aspect
@Component
public class WebLogAspect {

    /**
     * 定义一个切入点.
     * 解释下：
     * ~ 第一个 * 代表任意修饰符及任意返回值.
     * ~ 第二个 * 任意包名
     * ~ 第三个 * 代表任意方法.
     * ~ 第四个 * 定义在web包或者子包
     * ~ 第五个 * 任意方法
     * ~ .. 匹配任意数量的参数.
     */
    @Pointcut("execution(* com.xzc.one.controller..*.*(..))")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("***************************            WebLogAspect.doBefore            ***************************");
        log.info("URL:\t" + request.getRequestURL().toString());
        log.info("METHOD:\t" + request.getMethod());
        log.info("IP:\t" + request.getRemoteAddr());
        if (joinPoint.getArgs().length > 0) {
            if (joinPoint.getArgs()[0] instanceof Request) {
                String param = JSON.toJSONString(joinPoint.getArgs()[0]);
                log.info("PARAM:\t" + param);
            }
        }
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String name = (String) parameterNames.nextElement();
            log.info(name + ":" + request.getParameter(name));
        }
    }

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) {
        // log.info("RESPONSE:\t" + JsonStrObjUtil.obj2Str(ret));
        log.info("RESPONSE:\t" + JSON.toJSONString(ret));
        log.info("*************************          WebLogAspect.doAfterReturning          *************************");
    }

}
